package com.yanftch.stopcoding.ui

import com.intellij.openapi.application.ApplicationManager
import com.yanftch.stopcoding.BaseApplicationComponent
import com.yanftch.stopcoding.bean.HotBean
import com.yanftch.stopcoding.cb.RequestCallBack
import com.yanftch.stopcoding.common.network.ImageLoader
import com.yanftch.stopcoding.common.network.ImageLoader_imageIO_first
import com.yanftch.stopcoding.common.network.ImageResult
import com.yanftch.stopcoding.common.util.LogUtil
import com.yanftch.stopcoding.common.util.SizeUtils
import com.yanftch.stopcoding.common.util.ToastUtils
import com.yanftch.stopcoding.config.DefaultConfig
import com.yanftch.stopcoding.request.RequestManager
import com.yanftch.stopcoding.storage.PluginState
import com.yanftch.stopcoding.ui.rotate.RotatedTextPanel_ok
import com.yanftch.stopcoding.utils.FileUtils
import com.yanftch.stopcoding.utils.ImageConfig
import kotlinx.coroutines.*
import java.awt.*
import java.awt.datatransfer.StringSelection
import java.awt.event.*
import java.awt.image.BufferedImage
import javax.swing.*
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine


/**
 * 提示弹窗
 *
 *   Swing 开发一个弹窗，用 JFrame 来显示，kotlin代码编写
 *     要求：
 *     1.按下ESC键或者Enter键可以关闭弹窗
 *     2.弹窗的宽和高分别是屏幕宽高的80%
 *     3.弹窗的位置是屏幕中心
 *     4.弹窗的背景色是默认色
 *     5.弹窗的标题是“弹窗”
 *     6.弹窗的内容：左侧2/3的宽度是上下结构，上边90%的高度显示一张图片，下边10%的高度显示出来图片的链接；右侧1/3的宽度会显示一个自定义的Jpanel，用来显示一段文字，文字颜色是红色，文字大小是14，文字内容是“分析各种系统资源：CPU使用情况、显示（Vsync信号、卡顿市场）、一些核心函数的耗时”，文字点击后会进入系统默认浏览器，打开文字对应的链接
 *
 */
class StopCodingFrame(val frameTitle: String? = DefaultConfig.DEFAULT_DIALOG_TITLE) : JFrame() {
    private val TAG = "debug_StopCodingFrame"

    private val panelWidth = SizeUtils.getScreenWidth() * 0.95
    private val panelHeight = SizeUtils.getScreenHeight() * 0.90

    // 根布局
    val mainPanel = JPanel(BorderLayout())
    val leftPanel = JPanel(BorderLayout())
    val rightPanel = JPanel(BorderLayout())


    init {
        title = frameTitle
        isAlwaysOnTop = true
        isResizable = false // 禁止调整大小
        defaultCloseOperation = HIDE_ON_CLOSE

        // 设置宽高
        setSize(panelWidth.toInt(), panelHeight.toInt())
        // 居中显示
        setLocationRelativeTo(null)
        this.isUndecorated = false

        addKeyListener(object : KeyAdapter() {
            override fun keyPressed(e: KeyEvent?) {
                e?.let {
                    if (it.keyCode == KeyEvent.VK_ESCAPE || it.keyCode == KeyEvent.VK_ENTER) {
                        hidePop()
                    }
                }
            }
        })
        addView()
    }

    /**
     * 初始添加视图
     */
    private fun addView() {

        mainPanel.border = BorderFactory.createEmptyBorder(0, 10, 0, 10)
        contentPane.add(mainPanel)

        // 左侧占据整体宽度的2/3
        val leftWidth = panelWidth * 2 / 3
        leftPanel.preferredSize = Dimension((leftWidth).toInt(), panelHeight.toInt())
        mainPanel.add(leftPanel, BorderLayout.WEST)

        // 添加左边图片
//        leftPanel.add(imageLabel, BorderLayout.CENTER)

        mainPanel.add(rightPanel, BorderLayout.CENTER)
    }

    private fun updateView(data: Pair<ImageResult, ArrayList<HotBean>>) {
        updateLeft(data)
        updateRight(data)

        contentPane.revalidate() // 重新验证布局
        contentPane.repaint()    // 重新绘制组件
    }

    private fun updateLeft(data: Pair<ImageResult, ArrayList<HotBean>>) {
        // 清除所有的旧标签
        leftPanel.removeAll()
//        val imageLabel = JLabel()
//        imageLabel.icon = null

        // 更新图片
        val imageIcon = ImageIcon(data.first.image)
        val originalImage = imageIcon.image as BufferedImage
        val imagePanel = ImagePanel(originalImage)
//        imageLabel.icon = imageIcon

        leftPanel.add(imagePanel, BorderLayout.CENTER)
        // 重新布局和重绘
//        imageLabel.revalidate() // 重新验证布局
//        imageLabel.repaint()    // 重新绘制组件

        val link = data.first.realUrl
        LogUtil.d(TAG, "更新图片：imageIcon=${data.first.image.hashCode()}, link=$link")
        val text =
            "<span style='color:rgba(255, 255, 255, 0.4);'>图片来源(点击可复制)  </span><a href='$link' style='color: white;'>$link</a>"

        val linkLabel = JLabel("<html>$text</html>", SwingConstants.CENTER)
        linkLabel.border = BorderFactory.createEmptyBorder(10, 0, 10, 0)
        leftPanel.add(linkLabel, BorderLayout.SOUTH)

        // 添加鼠标监听器
        leftPanel.addMouseListener(object : MouseAdapter() {
            override fun mouseClicked(e: MouseEvent) {
                // 复制链接到剪贴板
                val stringSelection = StringSelection(link)
                val clipboard = Toolkit.getDefaultToolkit().systemClipboard
                clipboard.setContents(stringSelection, null)
                ToastUtils.showToast(this@StopCodingFrame, "图片链接已复制~")
            }
        })

        leftPanel.revalidate() // 重新验证布局
        leftPanel.repaint()    // 重新绘制组件

    }


    private fun updateRight(data: Pair<ImageResult, java.util.ArrayList<HotBean>>) {
        val list = arrayListOf<HotBean>()
        rightPanel.border = BorderFactory.createEmptyBorder(0, 10, 0, 0)
        val hotBeanList = data.second
        // 接口成功的判断
        val apiSuccess = !hotBeanList.isNullOrEmpty()
//        LogUtil.d(TAG, " apiSuccess=$apiSuccess, hotBeanList=" + BaseApplicationComponent.list)
        if (apiSuccess) {
            list.addAll(hotBeanList)
        } else {
            if (BaseApplicationComponent.list.isNotEmpty()) {
                list.addAll(BaseApplicationComponent.list.shuffled().take(10))
            }
        }
        // 只截取前边30条数据吧，过多也没啥用...
        val realHotBeanList = if (list.size > 30) {
            list.subList(0, 30)
        } else {
            list
        }
        val rotatedTextPanel = RotatedTextPanel_ok(panelWidth, panelHeight, realHotBeanList)
        val state: PluginState = ApplicationManager.getApplication().getService(PluginState::class.java)
        val textSrc = state.textSrc
        val canLink = DefaultConfig.canLink(textSrc)
        val typeLabel = JLabel(textSrc)
        // 设置为加粗
        val font = typeLabel.font.deriveFont(Font.BOLD, 20f) // 获取现有字体并设置为加粗
        typeLabel.font = font

        // 设置颜色为白色
        typeLabel.foreground = Color.WHITE
        typeLabel.border = BorderFactory.createEmptyBorder(10, 0, 10, 0)
        typeLabel.horizontalAlignment = SwingConstants.CENTER
        val titlePanel = CenteredLabelsPanel(
            textSrc,
            if (canLink) "(标题点击可跳转)" else "",
            if (apiSuccess) "" else "「$textSrc」 " + DefaultConfig.DEFAULT_ERROR_MESSAGE
        )
        titlePanel.border = BorderFactory.createEmptyBorder(10, 0, 10, 0)
        rightPanel.add(titlePanel, BorderLayout.NORTH)
//        val hintPanel = JLabel(DefaultConfig.DEFAULT_ERROR_MESSAGE)
//        rightPanel.add(hintPanel, BorderLayout.CENTER)
        rightPanel.add(rotatedTextPanel, BorderLayout.CENTER)
    }

    private fun initView(data: Pair<ImageIcon, ArrayList<HotBean>>) {

    }

    fun showPop(type: Int, imageSrc: String) {
        getData(type, imageSrc) { success, data ->
            if (success) {
                SwingUtilities.invokeLater {
                    updateView(data)
                    this.isVisible = true
                }
                SwingUtilities.invokeLater {
                }
            } else {

            }
        }
    }

    fun hidePop() {
        this.isVisible = false
    }


    private fun getData(
        type: Int, imageSrc: String, showUI: (success: Boolean, result: Pair<ImageResult, ArrayList<HotBean>>) -> Unit
    ) {
        GlobalScope.launch {
            try {
                val imageUrl = fetchImageUrl(imageSrc)
                // 使用 supervisorScope 来确保子协程异常互不影响
                val result = supervisorScope {
                    val imageDeferred = async {
                        try {
                            fetchImage(imageUrl)
                        } catch (e: Exception) {
                            LogUtil.d(TAG, "加载图片时发生错误：${e.message}")
                            ImageConfig.loadImage()?.let { ImageResult(it, "") } // 返回 null 或者处理异常
                        }
                    }

                    val textDeferred = async {
                        try {
                            fetchText(type)
                        } catch (e: Exception) {
                            LogUtil.d(TAG, "请求文字时发生错误：${e.message}")
                            kotlin.collections.ArrayList() // 返回 null 或者处理异常
                        }
                    }

                    // 等待两个任务都完成，并将结果转换为 Pair
                    Pair(imageDeferred.await(), textDeferred.await())
                }
                // 图片和文字都加载完成后，显示 JFrame
                SwingUtilities.invokeLater {
                    showUI.invoke(true, result as Pair<ImageResult, ArrayList<HotBean>>)
                }
            } catch (e: Exception) {
                e.printStackTrace()
                LogUtil.d(TAG, "加载图片或请求文字时发生错误：${e.message}")
            }
        }
    }

    private suspend fun fetchImageUrl(imageSrc: String): String {
        val imageSourceEnum = DefaultConfig.ImageSourceEnum.fromString(imageSrc)
        LogUtil.d(TAG, "fetchImageUrl: imageSourceEnum: index = " + imageSourceEnum.index + ", desc = " + imageSourceEnum.description)
        val url = imageSourceEnum.url

        // 模拟从某个接口获取 imageUrl 的逻辑
        // 实际上这里会是一个网络请求，类似于 OkHttp 请求获取图片地址
        return withContext(Dispatchers.IO) {
            // 假设这个 URL 是从接口返回的
            url ?: DefaultConfig.BING_RANDOM_URL
        }
    }

    // 请求图片资源
    private suspend fun fetchImage(url: String): ImageResult {
        return try {
            withContext(Dispatchers.IO) {
                val imageLoaderImageIOfirst = ImageLoader()
                val imageResult = imageLoaderImageIOfirst.loadImage(url) // 调用 ImageLoader 加载图片

                if (imageResult != null) {
                    LogUtil.d(TAG, "fetchImage: imageResult.realUrl = " + imageResult.realUrl)
                    // 如果图片加载成功，返回 ImageIcon
                    imageResult
                } else {
                    // 如果加载失败，返回默认的 ImageIcon
                    ImageResult(ImageConfig.loadImage()?:BufferedImage(0,0,0), "/files/image_01.jpeg")
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            ImageResult(ImageConfig.loadImage()?:BufferedImage(0,0,0), "/files/image_01.jpeg")
        }
    }

    // 请求文本资源
    private suspend fun fetchText(type: Int): ArrayList<HotBean> {
        try {
            return suspendCoroutine { continuation ->
                val requestManager = RequestManager()
                requestManager.executeRequest(type, object : RequestCallBack {
                    override fun onSuccess(list: ArrayList<HotBean>?) {
                        continuation.resume(list ?: ArrayList())
                    }

                    override fun onError(e: Exception?) {
                        val listError = ArrayList<HotBean>()
//                        val bean = HotBean()
//                        bean.title = DefaultConfig.DEFAULT_ERROR_MESSAGE
//                        listError.add(bean)
                        continuation.resume(listError)
//                        NotificationUtils.showNotification("错误", ""+e?.message)
//                        continuation.resumeWithException(e ?: Exception("未知错误"))
                    }
                })
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return ArrayList()
    }

    override fun processWindowEvent(e: WindowEvent?) {
        if (WindowEvent.WINDOW_CLOSING == e?.id) {
            LogUtil.d(TAG, "processWindowEvent: WINDOW_CLOSING")
            dispose()
        } else {
            super.processWindowEvent(e)
        }
    }
}